package com.nbicc.common.exception;

import com.nbicc.common.ResponseObj;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * Created by li on 17/12/22.
 * 在进入Controller之前，譬如请求一个不存在的地址，404错误。
 */
@ApiIgnore()
@Slf4j
@RestController
public class BeforeIntoControllerExceptionHandler implements ErrorController {

    @Autowired
    private ErrorAttributes errorAttributes;
    private static final String PATH = "/error";

    @Override
    public String getErrorPath() {
        return PATH;
    }

    @RequestMapping(value = PATH ,  method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ResponseObj error(HttpServletRequest request, HttpServletResponse response) {
        return buildBody(request,true);
    }

    private ResponseObj buildBody(HttpServletRequest request, Boolean includeStackTrace){
        Map<String,Object> errorAttributes = getErrorAttributes(request, includeStackTrace);
        Integer status=(Integer)errorAttributes.get("status");
        String path=(String)errorAttributes.get("path");
        String error=(String)errorAttributes.get("error");
        String messageFound=(String)errorAttributes.get("message");
        String message="";
        String trace ="";
        if(!StringUtils.isEmpty(path)){
            message=String.format("Requested path %s with result %s",path,messageFound);
        }
        if(includeStackTrace) {
            trace = (String) errorAttributes.get("trace");
            if(!StringUtils.isEmpty(trace)) {
                message += String.format(" and trace %s", trace);
            }
        }

        ResponseObj responseObj = new ResponseObj(status , error , message);
        responseObj.setBodyMap(errorAttributes);
        log.error(responseObj.toString());
        return responseObj;
    }

    private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(request);
        return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
    }

}
